/*
 * CImportArmory.java
 *
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 *
 * This file is part of JRogueDPS.
 *
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */

package paperdoll;

import geardatabase.CItem;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JOptionPane;
import jroguedps.CGlobal;
import org.dom4j.Document;
import org.dom4j.Node;
import paperdoll.CDollSlotType.DollSlotType;
import utility.CMessage;
import utility.CStatus;
import utility.CRemoteXML;
import utility.URLUTF8Encoder;

/**
 *
 * @author Mani
 */
public class CImportArmory {

    static public boolean importPlayer(String p_playerName, String p_realm, String p_region)
    {
        String l_domain = "";
        if (p_region.equals("EU"))
        {
            l_domain = "eu.wowarmory.com";
        }
        else
        {
            l_domain = "www.wowarmory.com";
        }

        // Get the character sheet first
        // "character-sheet.xml";
        CStatus.setStatus("Importing " + p_playerName + " from " + l_domain + " with 3s timeout");
        CRemoteXML l_remoteXML = new CRemoteXML();
        Document l_charXML = l_remoteXML.extractData("http://" + l_domain + "/" + "character-sheet.xml" + "?r=" + p_realm.replaceAll(" ", "+") + "&n=" + URLUTF8Encoder.encode(p_playerName));
        if (l_charXML == null)
        {
            CMessage.showError("Failed to get character data for " + p_playerName + " from the armory. There may be a problem with the Armory web site.");
            CStatus.idleStatus();
            return false;
        }
        
		// l_sheetType = "character-talents.xml";
        CStatus.setStatus("Importing talents from " + l_domain + " with 3s timeout");
        Document l_talentXML = l_remoteXML.extractData("http://" + l_domain + "/" + "character-talents.xml" + "?r=" + p_realm.replaceAll(" ", "+") + "&n=" + URLUTF8Encoder.encode(p_playerName));
        if (l_talentXML == null)
        {
            CMessage.showError("Failed to get character talent data for " + p_playerName + " from the armory. There may be a problem with the Armory web site.");
            CStatus.idleStatus();
            return false;
        }

		Node l_charInfo = l_charXML.selectSingleNode( "//page/characterInfo" );
        if (l_charInfo == null)
        {
            CMessage.showError("There was a problem with the armory web page. It maybe down for maintenance");
            CStatus.idleStatus();
            return false;
        }

        String l_errCode = l_charInfo.valueOf("@errCode");
        if (l_errCode.equals("noCharacter"))
        {
            CMessage.showError("Player " + p_playerName + " does not exist on the armory");
            CStatus.idleStatus();
            return false;
        }
        
		Node node = l_charXML.selectSingleNode( "//page/characterInfo/character" );
		String l_class = node.valueOf( "@class" );

        if (!l_class.toLowerCase().equals("rogue"))
        {
            CMessage.showError("Player " + p_playerName + " must be Rogue class");
            CStatus.idleStatus();
            return false;
        }

		String l_race = node.valueOf( "@race" );
        CGlobal.g_paperDoll.setRace(l_race);
		System.out.println("Class : " + l_class + "  Race : " + l_race);

        boolean l_getActive = true;
        List l_list = l_talentXML.selectNodes("//page/characterInfo/talents/talentGroup");
        if (l_list.size() > 1)
        {
            int l_result = CMessage.getConfirm3("Player has dual spec, do you want the active spec? (Choosing No will get the non-active spec)");
            if (l_result == JOptionPane.NO_OPTION)
            {
                // We want the alternative spec
                l_getActive = false;
            }

            if (l_result == JOptionPane.CANCEL_OPTION || l_result == JOptionPane.CLOSED_OPTION)
            {
                return false;
            }
        }

        CGlobal.g_paperDoll.clearItems();
        
        String l_talentString = "";
        Iterator l_iter=l_list.iterator();
        while(l_iter.hasNext()){
            Node l_specNode = (Node) l_iter.next();
            String l_activeGroup = l_specNode.valueOf("@active");
            if (l_activeGroup.equals(""))
            {
                // Secondary spec
                if (l_getActive == false)
                {
                    node = l_specNode.selectSingleNode("talentSpec");
                    l_talentString = node.valueOf("@value");
                    CImportArmory.setGlyphs(l_specNode);
                    break;
                }
            }
            else
            {
                // Primary spec
                if (l_getActive == true)
                {
                    node = l_specNode.selectSingleNode("talentSpec");
                    l_talentString = node.valueOf("@value");
                    CImportArmory.setGlyphs(l_specNode);
                    break;
                }
            }
        }

		System.out.println("Talent String : " + l_talentString);
        CStatus.setStatus("Building talents");
        CGlobal.g_talents.importTalentString(l_talentString);

        l_list = l_charXML.selectNodes("//page/characterInfo/characterTab/items/item");
        System.out.println("Number of slots used " + l_list.size());
        
        l_iter=l_list.iterator();
        while(l_iter.hasNext()){
            CStatus.setStatus("Building slots");
            Node l_itemNode = (Node) l_iter.next();
            String l_itemID = l_itemNode.valueOf("@id");
            String l_slot = l_itemNode.valueOf("@slot");
            String l_icon = l_itemNode.valueOf("@icon");
            String l_gem0Id = l_itemNode.valueOf("@gem0Id");
            String l_gem1Id = l_itemNode.valueOf("@gem1Id");
            String l_gem2Id = l_itemNode.valueOf("@gem2Id");
            String l_permanentEnchant = l_itemNode.valueOf("@permanentenchant");

            System.out.println("Item " + l_itemID + " slot " + l_slot + " Icon " + l_icon);

            if (l_slot.equals("0"))
            {
                // Head
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.HEAD);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.HEAD);
                setGems(DollSlotType.HEAD, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            } else if (l_slot.equals("1"))
            {
                // Neck
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.NECK);
                setGems(DollSlotType.NECK, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            } else if (l_slot.equals("2"))
            {
                // Shoulder
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.SHOULDERS);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.SHOULDERS);
                setGems(DollSlotType.SHOULDERS, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("4"))
            {
                // Chest
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.CHEST);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.CHEST);
                setGems(DollSlotType.CHEST, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("5"))
            {
                // Waist
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.WAIST);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.WAIST);
                setGems(DollSlotType.WAIST, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("6"))
            {
                // Legs
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.LEGS);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.LEGS);
                setGems(DollSlotType.LEGS, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("7"))
            {
                // Boots
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.FEET);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.FEET);
                setGems(DollSlotType.FEET, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("8"))
            {
                // Wrist
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.WRIST);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.WRIST);
                setGems(DollSlotType.WRIST, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("9"))
            {
                // Hands
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.HANDS);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.HANDS);
                setGems(DollSlotType.HANDS, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("10"))
            {
                // Ring 1
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.FINGER1);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.FINGER1);
            }else if (l_slot.equals("11"))
            {
                // Ring 2
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.FINGER2);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.FINGER2);
            }else if (l_slot.equals("12"))
            {
                // Trinket 1
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.TRINKET1);                
            }else if (l_slot.equals("13"))
            {
                // Trinket 2
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.TRINKET2);               
            }else if (l_slot.equals("14"))
            {
                // Cloak
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.BACK);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.BACK);
                setGems(DollSlotType.BACK, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("15"))
            {
                // Main Hand
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.MAINHAND);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.MAINHAND);
                setGems(DollSlotType.MAINHAND, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("16"))
            {
                // Off Hand
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.OFFHAND);
                CItem l_enchant = CGlobal.g_database.getItem(l_permanentEnchant, false);
                CGlobal.g_paperDoll.setEnchant(l_enchant, DollSlotType.OFFHAND);
                setGems(DollSlotType.OFFHAND, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }else if (l_slot.equals("17"))
            {
                // Ranged
                CItem l_item = CGlobal.g_database.getItem(l_itemID, true);
                CGlobal.g_paperDoll.setItem(l_item, DollSlotType.RANGED);
                setGems(DollSlotType.RANGED, l_item, l_gem0Id, l_gem1Id, l_gem2Id);
            }
        }

        l_list = l_charXML.selectNodes("//page/characterInfo/characterTab/professions/skill");
        System.out.println("Number of professions available " + l_list.size());

        CGlobal.g_paperDoll.clearProfessions();
        CStatus.setStatus("Getting professions");
        l_iter = l_list.iterator();
        int l_index = 0;
        while(l_iter.hasNext()){
            Node l_itemNode = (Node) l_iter.next();
            String l_profession = l_itemNode.valueOf("@name");
            CGlobal.g_paperDoll.setProfession(l_profession, l_index++, true);
        }

        CStatus.idleStatus();
        return true;
    }

    static private void setGlyphs(Node l_node)
    {
        List l_list = l_node.selectNodes("glyphs/glyph");
        CGlobal.g_talents.setGlyph("None", 0, true);
        CGlobal.g_talents.setGlyph("None", 1, true);
        CGlobal.g_talents.setGlyph("None", 2, true);
        int l_index = 0;
        if (l_list != null)
        {
            Iterator l_iter = l_list.iterator();
            while(l_iter.hasNext()){
                Node l_glyphNode = (Node) l_iter.next();
                String l_type = l_glyphNode.valueOf("@type");
                if (l_type.equals("major"))
                {
                    String l_glyphName = l_glyphNode.valueOf("@name");
                    l_glyphName = l_glyphName.substring(9, l_glyphName.length());
                    CGlobal.g_talents.setGlyph(l_glyphName, l_index++, true);
                }
            }
        }
    }

    static private void setGems(DollSlotType p_slotType, CItem p_item, String p_gem1, String p_gem2, String p_gem3)
    {
        ArrayList<CItem> l_gemList = new ArrayList<CItem>();
        l_gemList.add(CGlobal.g_database.getItem(p_gem1, true));
        l_gemList.add(CGlobal.g_database.getItem(p_gem2, true));
        l_gemList.add(CGlobal.g_database.getItem(p_gem3, true));

        int l_noOfSockets = p_item.getNumberOfSockets();
        for (int i = 0; i < p_item.getNumberOfSockets(); i++)
        {
            CGlobal.g_paperDoll.setGem(l_gemList.get(i), p_slotType, i);
        }

        // Waist can have eternal belt buckle providing an extra gem
        if (p_slotType == DollSlotType.WAIST)
        {
            // Check if gem exists outside of socket holder list size
            if (l_noOfSockets < l_gemList.size())
            {
                CItem l_extraGem = l_gemList.get(l_noOfSockets);
                if (l_extraGem.getId() != 0)
                {
                    CGlobal.g_paperDoll.setEnchant(CGlobal.g_database.getItem(3722), p_slotType);
                }

                CGlobal.g_paperDoll.setBBGem(l_extraGem, p_slotType);
            }

        } else 
        // Wrists and Hands can have extra sockets from Blacksmithing
        if (p_slotType == DollSlotType.WRIST || p_slotType == DollSlotType.HANDS)
        {
            // Check if gem exists outside of socket holder list size
            if (l_noOfSockets < l_gemList.size())
            {
                CGlobal.g_paperDoll.setBBGem(l_gemList.get(l_noOfSockets), p_slotType);
            }
        }
    }
}
